package im.composer.media.sound.storage;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

import im.composer.audio.engine.Out;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;

import org.jaudiolibs.audioservers.AudioConfiguration;
import org.tritonus.share.sampled.FloatInputStream;
import org.tritonus.share.sampled.FloatSampleBuffer;

public class AudioStreamIn extends Out implements AutoCloseable {

	protected AudioInputStream ais0;
	protected AudioInputStream ais;
	protected FloatInputStream fis;
	private FloatSampleBuffer buf1;
	private boolean ended = false;

	public AudioStreamIn(File file) throws UnsupportedAudioFileException, IOException {
		ais0 = AudioSystem.getAudioInputStream(file);
	}

	public AudioStreamIn(URL url) throws UnsupportedAudioFileException, IOException {
		ais0 = AudioSystem.getAudioInputStream(url);
	}

	public AudioStreamIn(InputStream in) throws UnsupportedAudioFileException, IOException {
		ais0 = in instanceof AudioInputStream?(AudioInputStream)in:AudioSystem.getAudioInputStream(in.markSupported()?in:new BufferedInputStream(in));
	}

	public AudioStreamIn(InputStream in, AudioFormat format) throws UnsupportedAudioFileException, IOException {
		ais0 = in instanceof AudioInputStream?AudioSystem.getAudioInputStream(format, (AudioInputStream) in):new AudioInputStream(in,format,-1);
	}

	@Override
	public synchronized void configure(AudioConfiguration context) throws Exception {
		super.configure(context);
		AudioFormat format = new AudioFormat(context.getSampleRate(), ais0.getFormat().getSampleSizeInBits(), context.getOutputChannelCount(), true, true);
		ais = AudioSystem.getAudioInputStream(format, ais0);
		fis = new FloatInputStream(ais);
		buf1 = new FloatSampleBuffer(context.getOutputChannelCount(),context.getMaxBufferSize(),context.getSampleRate());
	}

	@Override
	protected void computeBuffer() {
		buf1.makeSilence();
		fis.read(buf1);
		if(buf1.getSampleCount()>0){
			buf1.copyTo(buf, 0, buf1.getSampleCount());
		}else{
			buf.makeSilence();
			ended = true;
		}
	}

	public boolean isEnded(){
		return ended;
	}
	
	@Override
	public void close() throws Exception {
		fis.close();
		ais.close();
		ais0.close();
	}

}
